import _regeneratorRuntime from "@babel/runtime/regenerator";
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
import fetch from 'dva/fetch';
import { routerRedux } from 'dva/router';
import React from 'react';
import { notification } from 'antd';
import { getEnvConfig, getDvaApp } from "./iocUtils";
import intl from "./intl"; // import { API_HOST, AUTH_SELF_URL, LOGIN_URL, CPAAS_OAUTH } from './config';

import { filterNullValueObject, generateUrlWithGetParam, getAccessToken, removeAccessToken, removeAllCookie, getSession, setSession } from "./utils";
import { getMenuId } from "./menuTab";
notification.config({
  placement: 'bottomRight'
});

function checkStatus(_x) {
  return _checkStatus.apply(this, arguments);
}
/**
 * 如果 后端返回的 501 需要判断是不是逻辑正常的 501
 * @param {Error} e - 原始的错误
 */


function _checkStatus() {
  _checkStatus = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(response) {
    var errortext, res, error;
    return _regeneratorRuntime.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            if (!(response.status >= 200 && response.status < 300)) {
              _context.next = 2;
              break;
            }

            return _context.abrupt("return", response);

          case 2:
            _context.prev = 2;
            _context.next = 5;
            return response.json();

          case 5:
            res = _context.sent;
            errortext = res.message || response.statusText;
            _context.next = 12;
            break;

          case 9:
            _context.prev = 9;
            _context.t0 = _context["catch"](2);
            errortext = response.statusText;

          case 12:
            error = new Error(errortext);
            error.name = response.status;
            error.response = response;
            throw error;

          case 16:
          case "end":
            return _context.stop();
        }
      }
    }, _callee, null, [[2, 9]]);
  }));
  return _checkStatus.apply(this, arguments);
}

function catchNormalError(_x2) {
  return _catchNormalError.apply(this, arguments);
}

function _catchNormalError() {
  _catchNormalError = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(e) {
    var dvaApp, errorData;
    return _regeneratorRuntime.wrap(function _callee2$(_context2) {
      while (1) {
        switch (_context2.prev = _context2.next) {
          case 0:
            dvaApp = getDvaApp();

            if (!(e.name === 501)) {
              _context2.next = 15;
              break;
            }

            _context2.prev = 2;
            _context2.next = 5;
            return e.response.json();

          case 5:
            errorData = _context2.sent;

            // TODO: 这里使用了 全局变量 dvaApp
            // eslint-disable-next-line
            dvaApp._store.dispatch({
              type: 'error/updateState',
              payload: {
                normal501: errorData
              }
            }); // eslint-disable-next-line


            dvaApp._store.dispatch(routerRedux.push({
              pathname: '/exception/501'
            }));

            _context2.next = 13;
            break;

          case 10:
            _context2.prev = 10;
            _context2.t0 = _context2["catch"](2);
            throw e;

          case 13:
            _context2.next = 16;
            break;

          case 15:
            throw e;

          case 16:
          case "end":
            return _context2.stop();
        }
      }
    }, _callee2, null, [[2, 10]]);
  }));
  return _catchNormalError.apply(this, arguments);
}

var headers = {
  Pragma: 'no-cache',
  'Cache-Control': 'no-cache'
};
/**
 * Requests a URL, returning a promise.
 *
 * @param  {string} url       The URL we want to request
 * @param  {object} [options] The options we want to pass to "fetch"
 * @return {object}           An object containing either "data" or "err"
 */

export default function request(url, options) {
  var customOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

  var _getEnvConfig = getEnvConfig(),
      API_HOST = _getEnvConfig.API_HOST,
      AUTH_SELF_URL = _getEnvConfig.AUTH_SELF_URL,
      LOGIN_URL = _getEnvConfig.LOGIN_URL,
      CPAAS_OAUTH = _getEnvConfig.CPAAS_OAUTH;

  var dvaApp = getDvaApp();
  var defaultOptions = {
    credentials: 'include',
    headers: headers
  };
  var beforeCatch = customOptions.beforeCatch; // TODO: API MOCK 代理

  var newUrl = !url.startsWith('/api') && !url.startsWith('http') ? "".concat(API_HOST).concat(url) : url;

  var newOptions = _objectSpread(_objectSpread({}, defaultOptions), options);

  if (newOptions.method === 'POST' || newOptions.method === 'PUT' || newOptions.method === 'DELETE' || newOptions.method === 'PATCH') {
    if (!(newOptions.body instanceof FormData)) {
      newOptions.headers = _objectSpread({
        Accept: 'application/json',
        'Content-Type': 'application/json; charset=utf-8'
      }, newOptions.headers);
      newOptions.body = JSON.stringify(newOptions.body);
    } else {
      // newOptions.body is FormData
      newOptions.headers = _objectSpread({
        Accept: 'application/json'
      }, newOptions.headers);
    }
  } // 头查询参数


  if (newOptions.query) {
    var filterNullQuery = newOptions.query;

    if (newOptions.method === 'GET') {
      filterNullQuery = filterNullValueObject(newOptions.query);
    }

    newUrl = generateUrlWithGetParam(newUrl, filterNullQuery);
  }

  var accessToken = getAccessToken();

  if (accessToken) {
    newOptions.headers = _objectSpread(_objectSpread({}, newOptions.headers), {}, {
      Authorization: "bearer ".concat(accessToken)
    });
  }

  var MenuId = getMenuId();

  if (MenuId) {
    newOptions.headers = _objectSpread(_objectSpread({}, newOptions.headers), {}, {
      'H-Menu-Id': "".concat(MenuId)
    });
  }

  var fetchChain = fetch(newUrl, newOptions).then(checkStatus).then(function (response) {
    if (response.status === 204) {
      return {};
    }

    if (newOptions.responseType === 'blob') {
      return response.blob();
    }

    return newOptions.responseType === 'text' ? response.text() : response.json();
  });

  if (beforeCatch) {
    // beforeCatch 必须为方法
    fetchChain = fetchChain.catch(beforeCatch);
  }

  fetchChain = fetchChain.catch(catchNormalError).catch(function (e) {
    var status = e.name; // 监听到 401 错误 重新登陆
    // isErrorFlag 用来处理，只对第一个401做处理，后续不再处理，防止多次跳回token失效界面

    var isError = getSession('isErrorFlag'); // 获取当前的session isErrorFlag

    if (!isError) {
      // 如果没有isErrorFlag的session，设置为false
      setSession('isErrorFlag', false);
    } // setSession('isErrorFlag', false);


    if (status === 401) {
      // FIXME:已处理过一次401后就不再处理
      var cacheLocation = encodeURIComponent(window.location.toString());

      if (accessToken) {
        request("".concat(CPAAS_OAUTH, "/public/token/kickoff"), {
          method: 'POST',
          query: {
            access_token: accessToken
          }
        }).then(function (res) {
          if (res.kickoff === 1) {
            // 跳转到踢下线界面
            // eslint-disable-next-line
            dvaApp._store.dispatch(routerRedux.push({
              pathname: '/public/kickoff'
            }));

            setSession('redirectUrl', cacheLocation);
            setSession('isErrorFlag', false);
          } else {
            // token 失效, 跳转到 token失效页面
            dvaApp._store.dispatch(routerRedux.push({
              pathname: '/public/unauthorized'
            }));

            setSession('isErrorFlag', true); // 登陆后需要跳回的界面， 放到session中

            setSession('redirectUrl', cacheLocation);
          }
        });
        return;
      }

      removeAccessToken();
      removeAllCookie(); // self 接口报错

      if (newUrl.indexOf(AUTH_SELF_URL) !== -1) {
        // 如果是self接口401，跳转到登录界面
        // 由于 LOGIN_URL 可以 配置, 所以 做一次判断
        if (LOGIN_URL.includes('?')) {
          window.location.href = "".concat(LOGIN_URL, "&redirect_uri=").concat(cacheLocation); // 401 需要在登录后返回401的页面

          setSession('isErrorFlag', false); // 跳回登录界面后，isErrorFlag 设置为false， 表示下一次401会进行处理

          setSession('redirectUrl', cacheLocation);
        } else {
          window.location.href = "".concat(LOGIN_URL, "?redirect_uri=").concat(cacheLocation); // 401 需要在登录后返回401的页面

          setSession.apply('isErrorFlag', false); // 跳回登录界面后，isErrorFlag 设置为false， 表示下一次401会进行处理

          setSession('redirectUrl', cacheLocation);
        }

        return; // 正常流程 这里结束
      }

      if (!isError) {
        // 其他接口401，跳转到重新登录页面
        dvaApp._store.dispatch(routerRedux.push({
          pathname: '/public/unauthorized'
        }));

        setSession('isErrorFlag', true); // 登陆后需要跳回的界面， 放到session中

        setSession('redirectUrl', cacheLocation);
      }

      return; // return后不执行notification.error, 不再弹出401的提示框
    } // self 接口报错


    if (newUrl.indexOf(AUTH_SELF_URL) !== -1) {
      // self 接口报错后需要 跳转到错误页面
      return e;
    } // 监听到 网络请求错误
    // https://github.com/github/fetch/issues/201


    if (status === 'TypeError') {
      notification.error({
        message: intl.get('cpaas.common.notification.network.typeError').d('网络请求异常'),
        description: intl.get('cpaas.common.notification.typeError.description').d('请稍后重试')
      });
      return;
    }

    if (status === 501) {// 后端正常的报错/服务器报错
    }

    var m = require("../assets/icon_page_wrong.svg");

    if (m.__esModule) {
      m = m.default;
    }

    notification.error({
      icon: /*#__PURE__*/React.createElement(React.Fragment, null),
      message: /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("img", {
        src: m,
        alt: "",
        className: "ant-notification-notice-message-img"
      }), /*#__PURE__*/React.createElement("div", {
        className: "ant-notification-notice-message-content"
      }, intl.get("cpaas.common.requestNotification.".concat(status)) || e.message)),
      className: 'request error'
    });
  });
  return fetchChain;
}